/**
 * @fileoverview 
 * 클라이언트가 데이터 요청을 중앙 관리 하는 모듈.
 * 
 * @author luffy
 */
luffy.common.DataClient = jindo.$Class({	
	
	/**
	 * @constructor
	 * 
	 * @param {Object} oOptions : jindo.$Ajax 생성시 옵션으로 넣을 값
	 */
	$init : function(oOptions) {

		var self = this;
		this._progressing = false;
		this._timer = null;

		oOptions = oOptions || {};
		oOptions.type = 'XHR';
		oOptions.onload = function(oRes) {			
			luffy.common.DataCache.setData(self._currentRequest.sURL, self._currentRequest.oParam, oRes);
			self._onComplete('load', oRes);
		};
		oOptions.onerror = function(oRes) {
			self._onComplete('error', oRes);
		};
		oOptions.ontimeout = function(oRes) {
			self._onComplete('timeout', null);
		};

		this._timeout = oOptions.timeout || 0;
		delete oOptions.timeout;

		this._ajax = jindo.$Ajax('DUMMY', oOptions);
		
		this._currentRequest = {};

	},

	/**
	 * 요청에 대한 처리가 끝났을때 (응답이 왔든, 에러가 났든, 타임아웃이 되었든) 호출
	 * 
	 * @param {String} sType : 어떤 방법으로 끝났는지 (load : 정상로드, error : 에러, timeout : 타임아웃, abort : 강제중단)
	 * @param {$Ajax.Response) oRes : $Ajax 응답 객체
	 */
	_onComplete : function(sType, oRes) {

			// abort 해서 생긴 에러면 무시 ($Ajax 의 버그)
		if (sType == 'error' && oRes.status() <= 0)
			return;

		this._progressing = false;

		if (this._timer)
			clearTimeout(this._timer);
		this._timer = null;

		this.fireEvent(sType, {
			ajax : this._ajax,
			response : oRes
		});
		this.fireEvent('complete', {
			ajax : this._ajax,
			response : oRes
		});

	},

	/**
	 * XHR 요청
	 * 
	 * @param {String} sMethod : 요청 방법 (GET, POST)
	 * @param {String} sURL : 요청할 URL
	 * @param {Object} oParam : 요청시 파라미터
	 */
	request : function(sMethod, sURL, oParam) {

		var self = this;

		this.abort();

		oParam = oParam || {};

		/* Jindo $Ajax 의 패치로 필요없어짐
		if (sMethod.toUpperCase() == 'GET') {
			sURL += sURL.indexOf('?') != -1 ? '&' : '?';
			sURL += jindo.$H(oParam).toQueryString();
		}
		*/

		this._ajax._url = sURL;
		this._ajax.option( {
			method : sMethod
		});

		if (!this.fireEvent('request', {
			ajax : this._ajax,
			data : oParam
		}))
			return false;

		this._progressing = true;
		
		this._currentRequest.sURL = sURL;
		this._currentRequest.oParam = oParam;
		
		if(sMethod == "GET"){
			var oCacheData = luffy.common.DataCache.getData(sURL,oParam);
			if(oCacheData){
				this._ajax.onload(oCacheData);
				return true;
			}			
		}		
		this._ajax.request(oParam);
		
		if (this._progressing && this._timeout) {
			this._timer = setTimeout( function() {
				self.abort();
				self.fireEvent('timeout');
			}, this._timeout * 1000);
		}

		return true;

	},

	/**
	 * XHR 요청 중단
	 */
	abort : function() {

		if (this._progressing)
			this._onComplete('abort', {
				ajax : this._ajax
			});

		this._ajax.abort();

	},

	/**
	 * 현재 요청에 대한 처리가 진행중인지 반환
	 * 
	 * @return {Boolean}
	 */
	isProgressing : function() {
		return this._progressing;
	}
}).extend(nhn.Component);